home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-12-08 | 43.2 KB | 1,228 lines | [TEXT/R*ch] |
- C.S.M.P. Digest Wed, 27 Jan 93 Volume 2 : Issue 6
-
- Today's Topics:
-
- Driving mac program from another
- Detecting reboot or startup
- Software control of landscape/not landscape
- Preloading ALL code segments...?
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
-
- The digest is a collection of article threads from the internet newsgroup
- comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
- regularly and want an archive of the discussions. If you don't know what a
- newsgroup is, you probably don't have access to it. Ask your systems
- administrator(s) for details. If you don't have access to news, there is
- no way that I know of for you to post articles to the group.
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- cs.uoregon.edu). Article threads are not added to the digest until the last
- article added to the thread is at least one month old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
- [128.223.8.8] in the directory /pub/mac/csmp-digest. Be sure to read the
- file /pub/mac/csmp-digest/README before downloading any files. The most
- recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
- directory /info-mac/digest/csmp. If you don't have ftp capability, the sumex
- archive has a mail server; send a message with the text '$MACarch help' (no
- quotes) to LISTSERV@ricevm1.rice.edu for more information.
-
- The digest is also available via email. Just send a note saying that you
- want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
- automatically receive each new issue as it is created. Sorry, back issues
- are not available through the mailing list.
-
- Send administrative mail to mkelly@cs.uoregon.edu.
-
-
- -------------------------------------------------------
-
- From: ray@philmtl.philips.ca (Ray Dunn)
- Subject: Driving mac program from another
- Date: 18 Dec 92 04:14:29 GMT
- Organization: Not Philips.
-
- Question from someone fairly Mac illiterate but who has a serious need to
- know:
-
- Given a Mac program which normally takes much mouse events and keyboard
- input, is it possible (easily/with difficulty) to have that program run
- automatically with the input being generated by another program?
-
- To save time, I'd appreciate an email answer, and will summarize replies
- back to here.
-
- Thanks.
- - --
- Ray Dunn at home | Beaconsfield, Quebec | Phone: (514) 630 3749
- ray@philmtl.philips.ca | ray@cam.org | uunet!sobeco!philmtl!ray
-
- +++++++++++++++++++++++++++
-
- From: d88-jwa@dront.nada.kth.se (Jon Wtte)
- Date: 18 Dec 92 17:50:34 GMT
- Organization: Royal Institute of Technology, Stockholm, Sweden
-
- In <1992Dec18.041429.22979@philmtl.philips.ca> ray@philmtl.philips.ca (Ray Dunn) writes:
-
- >Given a Mac program which normally takes much mouse events and keyboard
- >input, is it possible (easily/with difficulty) to have that program run
- >automatically with the input being generated by another program?
-
- Well, set "null events" on, and patch into the jGNEFilter. For
- every NULL event, instead add your own keyDown events, with a nullEvent
- sprinkled in here & yjere for good measure and recovery.
-
- However, affecting someone elses jGNEFilter means patching in on
- INIT time; so you'll have to have a cool INIT/APPL combo.
-
- Cheers,
-
- / h+
-
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
- Engineering: "How will this work?" Science: "Why will this work?" Management:
- "When will this work?" Liberal Arts: "Do you want fries with that?"
- -- Jesse N. Schell
-
- +++++++++++++++++++++++++++
-
- From: absurd@apple.apple.com (Tim Dierks, software saboteur)
- Date: Fri, 18 Dec 1992 22:23:37 GMT
- Organization: MacDTS Marauders
-
- In article <1992Dec18.175034.23523@kth.se>, d88-jwa@dront.nada.kth.se (Jon
- Wtte) wrote:
- > In <1992Dec18.041429.22979@philmtl.philips.ca> ray@philmtl.philips.ca (Ray Dunn) writes:
- > However, affecting someone elses jGNEFilter means patching in on
- > INIT time; so you'll have to have a cool INIT/APPL combo.
-
- Actually, jGNEFilter is not (currently) swapped at process switch times;
- if you change jGNEFilter in one app, you've changed it in all of them.
- This makes life a little scary for jGNEFilter writers; if more than one
- person patches this vector, the earlier ones are never allowed to go
- away, because pointers to their code are stashed somewhere unknown.
-
- Scary, huh?
-
- Tim Dierks
- MacDTS pinball addict (TM)
-
- ---------------------------
-
- From: cmcclary@ucs.indiana.edu (Charles McClary)
- Subject: Detecting reboot or startup
- Date: 15 Dec 92 16:40:03 GMT
- Organization: Indiana University
-
- What is the best/preferred method for an application to detect if the
- system has been rebooted or restarted since it (the application) last ran.
-
- Thanks,
- Charlie McClary
- Indiana Univ.
- cmcclary@indiana.edu
-
- +++++++++++++++++++++++++++
-
- From: steve.herman%express@freedom.msfc.nasa.gov (Steve Herman)
- Date: 16 Dec 92 19:44:51 GMT
- Organization: BCSS
-
- In article <cmcclary-151292113831@mcclary-mac.ucs.indiana.edu>,
- cmcclary@ucs.indiana.edu (Charles McClary) wrote:
- >
- > What is the best/preferred method for an application to detect if the
- > system has been rebooted or restarted since it (the application) last ran.
- >
-
- At one time I had attempted to do this by doing the following:
-
- 1. Get the current time in seconds using GetDateTime()
- 2. Get number of ticks since last startup using TickCount()
- 3. Divide #2 by 60 to get seconds since startup.
- 4. Subtract #3 from #1 to get time in seconds of startup
- 5. Save this value to a file.
- 6. Whenever my application would startup it would perform steps 1-4 and
- compare to the value stored in the file. If the values matched, plus or
- minus a fudge factor I built in, then I would assume the machine had not
- been re-booted since I last ran.
-
- However, this would obviously break if the user changed the date/time on
- his Mac. I also found out that TickCount is incremented during the
- vertical retrace interrupt and whenever this interupt is disabled the ticks
- are not incremented so it gradually loses time. On my particular machine it
- was losing almost a minute for each hour my machine was up. This was going
- to make my built-in fudge factor unrealistic.
-
- I attempted to find another way to do this but eventually gave up. I
- would like to know if you discover a reliable method.
-
-
- - ----------------------------------------------------
- - - Steve Herman - BCSS
- - - Boeing Computer Support Services
- - - Huntsville, AL
- - ----------------------------------------------------
-
- +++++++++++++++++++++++++++
-
- From: d88-jwa@dront.nada.kth.se (Jon Wtte)
- Date: 16 Dec 92 13:28:25 GMT
- Organization: Royal Institute of Technology, Stockholm, Sweden
-
- In <cmcclary-151292113831@mcclary-mac.ucs.indiana.edu> cmcclary@ucs.indiana.edu (Charles McClary) writes:
-
- >What is the best/preferred method for an application to detect if the
- >system has been rebooted or restarted since it (the application) last ran.
-
- Install a gestalt selector with your own signature as selector code.
-
- If it's there, the application run previously during this "session."
- The selector code should reside in the system heap, and could simply
- return a 0 as result; you would test for presence, not return code.
-
- Cheers,
-
- / h+
-
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
-
- Nothing crashes like a Macintosh.
- -- Guy Kawasaki
-
- +++++++++++++++++++++++++++
-
- From: kent@lloyd.Camex.COM (Kent Borg)
- Organization: Camex Inc., Boston MA
- Date: Thu, 17 Dec 1992 18:19:10 EST
-
- In article <1992Dec16.132825.13170@kth.se> d88-jwa@dront.nada.kth.se (Jon Wtte) writes:
- >In <cmcclary-151292113831@mcclary-mac.ucs.indiana.edu> cmcclary@ucs.indiana.edu (Charles McClary) writes:
- >
- >>What is the best/preferred method for an application to detect if the
- >>system has been rebooted or restarted since it (the application) last ran.
- >
- >Install a gestalt selector with your own signature as selector code.
- >
- >If it's there, the application run previously during this "session."
- >The selector code should reside in the system heap, and could simply
- >return a 0 as result; you would test for presence, not return code.
-
- I expected Jon to post that answer. He is right, do it that way.
- However, if you want to run on old systems which don't have Gestalt,
- there is another (related) approach.
-
- Put a little something else in the System heap, note its location in a
- file, and check whether it is still there when you next launch.
- (Rather than using a file to record the address you might walk the
- heap to find it. I doubt Apple will change the heap structure in
- *old* systems.)
-
- Off the top of my head, I can't remember how an app can allocate a
- handle in the System heap and also prevent Multifinder from cleaning
- up and deleting it for you when you exit, but loading a resource into
- the System heap and then detaching it should work. Shouldn't it?
-
-
- - --
- Kent Borg kent@camex.com or kentborg@aol.com (when it is *working*)
- H:(617) 776-6899 W:(617) 426-3577
- As always, things look better when some costs are left out.
- -Economist 3-28-92 p. 94
-
- +++++++++++++++++++++++++++
-
- From: tj@kona.cs.ucla.edu (Tom Johnson)
- Date: 18 Dec 92 18:12:53 GMT
- Organization: UCLA, Computer Science Department
-
- cmcclary@ucs.indiana.edu (Charles McClary) asked:
- >>
- >>>What is the best/preferred method for an application to detect if the
- >>>system has been rebooted or restarted since it (the application) last ran.
-
- And d88-jwa@dront.nada.kth.se (Jon Wtte) answered:
- >>
- >>Install a gestalt selector with your own signature as selector code.
- >>
-
- In considering old systems that don't have Gestalt, kent@lloyd.Camex.COM
- (Kent Borg) suggested:
- >
- >Put a little something else in the System heap, note its location in a
- >file, and check whether it is still there when you next launch.
- >(Rather than using a file to record the address you might walk the
- >heap to find it. I doubt Apple will change the heap structure in
- >*old* systems.)
- >
- >Off the top of my head, I can't remember how an app can allocate a
- >handle in the System heap and also prevent Multifinder from cleaning
- >up and deleting it for you when you exit, but loading a resource into
- >the System heap and then detaching it should work. Shouldn't it?
- >
-
- This reminded me of how I used to handle communication between a cdev and
- an INIT before Gestalt was available. I simply installed a small driver
- and used it to pass variables back and forth.
-
- For this purpose (detecting whether the machine has been rebooted, the
- driver wouldn't really have to do anything - it could be a very simple
- shell. As with Jon's Gestalt method, you would simply check for an error
- - in this case one returned by OpenDriver().
-
- Tom
- - --
- Tom Johnson "They say Confucious does his crossword with a pen."
- tj@cs.ucla.edu -Tori Amos
-
- +++++++++++++++++++++++++++
-
- From: paul@taniwha.UUCP (Paul Campbell)
- Date: 19 Dec 92 03:54:21 GMT
- Organization: Taniwha Systems Design
-
- In article <cmcclary-151292113831@mcclary-mac.ucs.indiana.edu> cmcclary@ucs.indiana.edu (Charles McClary) writes:
- >What is the best/preferred method for an application to detect if the
- >system has been rebooted or restarted since it (the application) last ran.
-
- Assuming you saved the time your app last ran in a file and resource and
- then read it back again into 'last_time_ran' then try:
-
- unsigned long last_time_ran, now;
-
- ReadDateTime(&now);
- if ((now - (TickCount()/CLOCKS_PER_SEC)) > last_time_ran) {
- // - we rebooted since last time we ran
- }
-
- Paul
- - --
- Paul Campbell UUCP: ..!mtxinu!taniwha!paul AppleLink: CAMPBELL.P
- Use up your Quayle jokes now while they're still good "Quayle for Pres. in '94"
- Q: Why is Marilyn Quayle like Marion Barry?
- A: They both suck a little dope.
-
- ---------------------------
-
- From: bowman@reed.edu (Mr. Stress Tensor)
- Subject: Software control of landscape/not landscape
- Date: 18 Dec 92 20:51:37 GMT
- Organization: Reed College, Portland, OR
-
- What's the best way to force landscape printing? It would be nice if PrGeneral
- would do it, but apparently it can't (?). I'd love to be wrong about that.
- It seems a bad idea to mucking directly into the print record, since I certainly
- can't test on every printer there is. It also seems like it might be possible
- to fake a mousedown in the Page Setup dialog so that it defaults to landscape,
- but I'd like, if possible, to be able to use the print record for various
- nefarious porpoises.
-
- Thanks,
- bobo In seeking the unattainable,
- bowman@reed.edu simplicity only gets in the way.
- Ask not what's inside your head but what your head's inside of. - W. Mace
-
- +++++++++++++++++++++++++++
-
- From: engber@ils.nwu.edu (Mike Engber)
- Date: 22 Dec 92 14:51:06 GMT
- Organization: The Institute for the Learning Sciences
-
-
- Attached is the relevant code extracted from SaveATree. It's THINK C code.
-
- Basically, there is no official way to get a landscape print record,
- but it's somewhat common knowledge that the orientation is controlled
- by single bit in the print record (once source for this info is
- MacRevealed vol 3). This bit is used for Apple printers and deskwriters
- - - don't have access to other types of printers to check it out.
-
- My conservative approach is to:
- 1) flip the bit
- 2) use PrValidate to make sure I didn't trash the print record - i.e.
- this driver can't handle this bit being flipped.
- 3) use PrGeneral to make sure flipping the bit put the print record
- into landscape mode (instead of doing something else)
- 4) if 1-3 didn't work, I prompt the user to pick a landscape record
- from the PrStlDialog I subsequently display. This is sure to work
- unless the user screws up (I display the landscape Icon in the dialog
- in an attempt to make it more foolproof).
- 5) Once I get a landscape record I save it away so I'll never have
- to do this again.
-
- This should work pretty well. I don't think it violate any guidlines
- (too badly). And I've never had and problems reported wrt to SaveATree
- doing it. Some cavats:
-
- 1) the printer must have PrGeneral implemented along with the getRotnOp
- opcode (I assume most do nowadays)
-
- 2) Older HP deswriter drivers have PrGeneral & getRotnOp implementd, but
- don't return a success error code from PrGeneral. So flipping the bit
- works, but since PrGeneral says it's didn't - I end up prompting the
- user anyway. This bug has been fixed in the more recent drivers.
-
- - -ME
-
- - ---
-
- void PrintPromptedStyle(THPrint printRecH, Boolean landscape){
- Alert(DU_CenterALRT(landscape ? L_SETUP_ALERT_ID : P_SETUP_ALERT_ID),0L);
- PrOpen();
- PrStlDialog(printRecH);
- PrClose();
- }
-
- static Boolean PrRotn(THPrint printRecH, Boolean* landscape){
- TGetRotnBlk rotnBlk;
-
- rotnBlk.iOpCode = getRotnOp;
- rotnBlk.hPrint = printRecH;
- PrGeneral((Ptr)&rotnBlk);
-
- if(rotnBlk.iError == noErr){
- *landscape = rotnBlk.fLandscape ? true : false;
- return true;
- }else{
- return false;
- }
- }
-
- void PrintDefaultRotn(THPrint printRecH, Boolean landscape){
- Boolean is_landscape;
- static TPrint landscapeTPrint;
- static TPrint portraitTPrint;
- static Boolean landscapeStored = false;
- static Boolean portraitStored = false;
-
- PrOpen();
- if(PrintError("\pprint.c: PrintDefaultRotn()","\pPrOpen") != noErr){
- PrClose();
- return;
- }
-
- PrValidate(printRecH);
-
- if(PrRotn(printRecH,&is_landscape)){
- if(is_landscape != landscape){
- /* toggle the bit */
- (*printRecH)->prStl.wDev ^= 0x02;
- /* make sure it worked */
- PrValidate(printRecH);
- if(PrRotn(printRecH,&is_landscape) && is_landscape==landscape){
- PrClose();
- return;
- }
- }else{
- /* it was ok to begin with */
- PrClose();
- return;
- }
- }
-
- /*
- If we reach this point either PrGeneral/getRotnOp or the
- bit toggling won't work on this printer. So we'll prompt
- the user & display a style dlog (ugh!).
- */
- PrClose();
-
- if(landscape){
- if(landscapeStored){
- **printRecH = landscapeTPrint;
- }else{
- PrintPromptedStyle(printRecH,landscape);
- landscapeStored = true;
- landscapeTPrint = **printRecH;
- }
- }else{
- if(portraitStored){
- **printRecH = portraitTPrint;
- }else{
- PrintPromptedStyle(printRecH,landscape);
- portraitStored = true;
- portraitTPrint = **printRecH;
- }
- }
- }
-
- ---------------------------
-
- From: hanord@rubin.dbe (Haavard Nord)
- Subject: Preloading ALL code segments...?
- Date: 1 Dec 92 18:43:46 GMT
- Organization: Department of Biomedical Engineering
-
- Maybe this is a common question, but I hope someone can help me anyway.
-
- I have a faceless background application that communicates with a client
- (external 4D procedure) via PPC. The background application uses asynch
- PPC services, i.e. its completion routines are some sort of interrupt.
-
- When such an interrupt is invoked, the mac thinks that the foreground
- application is still current. When the background application makes calls
- to procedures in other CODE segments, the segment loader isn't able to
- load anything for the background. I've tried setting the global CurMap
- variable with UseResFile(), but it does nothing.
-
- The solution is to have all code segments preloaded. How can I do this?
- There are more than 30 segments, and some of these come from library
- files. I could use the '-sn myseg=Main' option with Link, but that
- requires that I know all segments, and the number of segments may change
- when the program is modified.
-
- Another solution is to initially make calls to all functions I intend to
- use from the interrupt procedure, but that is as stupid as using -sn.
-
- So --- what can I do? How can I (easily) load all segments at once when
- the background application starts, or how can I use UseResFile()?
-
- Thanks,
-
- - -hanord
- - --
- ===============================================================================
- Haavard Nord email: hanord@ibt.unit.no
- Dept. of Biomedical Engineering phone: +47 7 598685
- Trondheim, Norway fax: +47 7 598613
- ===============================================================================
-
- +++++++++++++++++++++++++++
-
- Organization: Royal Institute of Technology, Stockholm, Sweden
- Date: Tue, 1 Dec 1992 19:29:55 GMT
-
- In <HANORD.92Dec1194346@rubin.dbe> hanord@rubin.dbe (Haavard Nord) writes:
-
- >The solution is to have all code segments preloaded. How can I do this?
- >There are more than 30 segments, and some of these come from library
- >files. I could use the '-sn myseg=Main' option with Link, but that
- >requires that I know all segments, and the number of segments may change
- >when the program is modified.
-
- >Another solution is to initially make calls to all functions I intend to
- >use from the interrupt procedure, but that is as stupid as using -sn.
-
- >So --- what can I do? How can I (easily) load all segments at once when
- >the background application starts, or how can I use UseResFile()?
-
- You, of course, cannot load resources under interrupt time, since
- you can do NOTHING that would move memory, and loading resources
- or calling across boundaries certainly do.
-
- Now, what do you want to do in an interrupt service routine that
- would be so complicated as to require intra-segment calls? That would
- probably take time, and time during interrupt handling is CRITICAL!
- The mac is COMPLETELY FROZEN during interrupt servicing, and you
- don't want to be cruel to your users, right?
-
- What you should do, is pre-allocate what buffers you need, and
- store whatever data comes in there, and set a flag that your main
- event loop will see next time through, and THEN do whatever you
- want to do. This is the only safe & fair way of doing "it."
-
- If you have to pre-load all code resources, just do a simple:
-
- void
- PreLoadAllCode ( void )
- {
- Handle h ;
- int i ;
-
- SetResLoad ( 0 ) ;
-
- for ( i = Count1Resources ( 'CODE' ) ; i > 0 ; i -- ) {
-
- h = Get1IndResource ( 'CODE' , i ) ;
- if ( * h ) {
-
- HLock ( h ) ;
-
- } else {
-
- LoadResource ( h ) ;
- if ( ResError ( ) ) {
-
- SetResLoad ( 1 ) ;
- FailHorribly ( ResError ( ) ) ;
-
- } else {
-
- HUnlock ( h ) ;
- MoveHHi ( h ) ;
- HLock ( h ) ;
- }
- }
- }
-
- SetResLoad ( 1 ) ;
- }
-
-
- But, as I said, since you can call virtually NO toolbox traps
- either directly or indirectly during interrupt time; don't.
- And without calling the toolbox, there's not much more you can
- do but set a flag, and maybe queue a pre-prepared reply.
-
- Cheers,
-
- / h+
-
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
-
- "From now on I will re-label the EQ on the deck as Fizz and Wobble
- instead of HF and LF."
-
- +++++++++++++++++++++++++++
-
- From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
- Date: 2 Dec 92 09:07:54 +1300
- Organization: University of Waikato, Hamilton, New Zealand
-
- In article <HANORD.92Dec1194346@rubin.dbe>, hanord@rubin.dbe (Haavard Nord) writes:
- > Maybe this is a common question, but I hope someone can help me anyway.
- >
- > I have a faceless background application that communicates with a client
- > (external 4D procedure) via PPC. The background application uses asynch
- > PPC services, i.e. its completion routines are some sort of interrupt.
- >
- > When such an interrupt is invoked, the mac thinks that the foreground
- > application is still current. When the background application makes calls
- > to procedures in other CODE segments, the segment loader isn't able to
- > load anything for the background. I've tried setting the global CurMap
- > variable with UseResFile(), but it does nothing.
-
- Remember that loading code segments means allocating memory, which means
- you can't do it at interrupt time.
-
- > The solution is to have all code segments preloaded.
-
- This is the right idea.
-
- > How can I do this?
- > There are more than 30 segments, and some of these come from library
- > files. I could use the '-sn myseg=Main' option with Link, but that
- > requires that I know all segments, and the number of segments may change
- > when the program is modified.
-
- There's another directive , '-sg', which, among other things, takes the
- segment names in the opposite order to '-sn'. If you just use it in a form like
-
- -sg Everything
-
- then *all* your code gets put into a single segment called "Everything".
- This is probably the simplest solution, if your program isn't too large.
-
- > Another solution is to initially make calls to all functions I intend to
- > use from the interrupt procedure, but that is as stupid as using -sn.
-
- It may be clumsy, but in many cases it's the only way. What you actually have
- to do is make a call to one routine in every *segment* that contains routines
- that might be used by your interrupt code. You could add a dummy routine to
- each such segment, specifically for this purpose.
-
- This means you have to keep careful track of the segments in your program.
- But do you really need over 30 of them? You're probably better off merging
- a few of them with -sn or -sg directives.
-
- Lawrence D'Oliveiro fone: +64-7-856-2889
- Computer Services Dept fax: +64-7-838-4066
- University of Waikato electric mail: ldo@waikato.ac.nz
- Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00
-
- +++++++++++++++++++++++++++
-
- From: keith@taligent.com (Keith Rollin)
- Organization: Taligent
- Date: Tue, 1 Dec 1992 21:14:23 GMT
-
- In article <HANORD.92Dec1194346@rubin.dbe>, hanord@rubin.dbe (Haavard Nord)
- wrote:
- >
- > The solution is to have all code segments preloaded. How can I do this?
- > There are more than 30 segments, and some of these come from library
- > files.
-
- int i;
- for (i = 0; i < kNumberOfSegs; ++i)
- LoadSeg(i);
-
- - -----
- Keith Rollin
- Phantom Programmer
- Taligent, Inc.
-
- +++++++++++++++++++++++++++
-
- From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
- Date: 2 Dec 92 17:32:50 +1300
- Organization: University of Waikato, Hamilton, New Zealand
-
- tte) writes:
- >
- > If you have to pre-load all code resources, just do a simple:
- >
- > void
- > PreLoadAllCode ( void )
- > {
- > Handle h ;
- > int i ;
- >
- > SetResLoad ( 0 ) ;
- >
- > for ( i = Count1Resources ( 'CODE' ) ; i > 0 ; i -- ) {
- >
- > h = Get1IndResource ( 'CODE' , i ) ;
- > if ( * h ) {
- >
- > HLock ( h ) ;
- >
- > } else {
- >
- > LoadResource ( h ) ;
- > if ( ResError ( ) ) {
- >
- > SetResLoad ( 1 ) ;
- > FailHorribly ( ResError ( ) ) ;
- >
- > } else {
- >
- > HUnlock ( h ) ;
- > MoveHHi ( h ) ;
- > HLock ( h ) ;
- > }
- > }
- > }
- >
- > SetResLoad ( 1 ) ;
- > }
-
- This routine isn't going to help. It's just a way of doing at run time
- what you can do at link time by specifying "-ra =preload". Sure, the CODE
- resources will all be in memory, but the jump tables aren't going to be
- set up. The segment loader will still make its own Resource Manager calls
- to find those segments, which will mean traversing resource maps, which is
- not going to work very nicely at interrupt time.
-
- Lawrence D'Oliveiro fone: +64-7-856-2889
- Computer Services Dept fax: +64-7-838-4066
- University of Waikato electric mail: ldo@waikato.ac.nz
- Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00
-
- +++++++++++++++++++++++++++
-
- From: absurd@apple.apple.com (Tim Dierks, software saboteur)
- Date: Wed, 2 Dec 1992 07:48:39 GMT
- Organization: MacDTS Marauders
-
- In article <keith-011292131150@kip-15.taligent.com>, keith@taligent.com
- (Keith Rollin) wrote:
- >
- > In article <HANORD.92Dec1194346@rubin.dbe>, hanord@rubin.dbe (Haavard Nord)
- > wrote:
- > >
- > > The solution is to have all code segments preloaded. How can I do this?
- > > There are more than 30 segments, and some of these come from library
- > > files.
- >
- > int i;
- > for (i = 0; i < kNumberOfSegs; ++i)
- > LoadSeg(i);
- >
- > -----
- > Keith Rollin
- > Phantom Programmer
- > Taligent, Inc.
-
- I really hate to contradict Mr. Rollin, because there's a certain
- lurking suspicion that I could be incorrect, but this won't help
- for 3 reasons: first, LoadSeg is a very special trap; it requires
- that the code that calls it be structured in a particular way:
- first, the offset, hard coded as a constant into the code (2 bytes),
- then an instruction which loads the segment number onto the stack
- (4 bytes) and the LoadSeg trap (2 bytes). All this makes a jump
- table entry, and is described and depicted on page 61 of Inside
- Mac II. Second, LoadSeg never returns, because it's intended only
- as a mechanism for dispatching to routines in unloaded segments;
- this will cause this loop to never get to its second iteration.
- Third, due to these limitations, there isn't any prototype for
- LoadSeg; as far as I know, it can't be called from C or Pascal
- without writing your own prototype (and then would be very
- difficult to call correctly).
-
- Tim Dierks
- Speaking solely for himself
-
- +++++++++++++++++++++++++++
-
- From: scott@phylo.life.uiuc.edu (Scott Howard)
- Date: 2 Dec 92 15:05:11 GMT
- Organization: University of Illinois at Urbana
-
- This seems to be too simple to work, but how about
- Using ResEdit to Flag all your code Resources as Pre-Load
- and No-Purge?
- - --
- Coffee Facts from Dr. Science:
- 1) You can never brew coffee too strong.
- 2) You can never drink too much coffee.
- 3) Coffee does not make you nervous. Your own inadequacies do that.
- Coffee merely increases your perception of your own inadequacies.
- 4) Tea is to coffee as ginger ale is to Scotch.
-
- +++++++++++++++++++++++++++
-
- From: keith@taligent.com (Keith Rollin)
- Date: 2 Dec 92 20:50:17 GMT
- Organization: Taligent
-
- In article <absurd-011292234220@seuss.apple.com>, absurd@apple.apple.com
- (Tim Dierks, software saboteur) wrote:
- >
- > In article <keith-011292131150@kip-15.taligent.com>, keith@taligent.com
- > (Keith Rollin) wrote:
- > >
- > > In article <HANORD.92Dec1194346@rubin.dbe>, hanord@rubin.dbe (Haavard Nord)
- > > wrote:
- > > >
- > > > The solution is to have all code segments preloaded. How can I do this?
- > > > There are more than 30 segments, and some of these come from library
- > > > files.
- > >
- > > int i;
- > > for (i = 0; i < kNumberOfSegs; ++i)
- > > LoadSeg(i);
- >
- > I really hate to contradict Mr. Rollin, because there's a certain
- > lurking suspicion that I could be incorrect, but this won't help
- > for 3 reasons: first, LoadSeg is a very special trap; it requires
- > that the code that calls it be structured in a particular way:
- > first, the offset, hard coded as a constant into the code (2 bytes),
- > then an instruction which loads the segment number onto the stack
- > (4 bytes) and the LoadSeg trap (2 bytes). All this makes a jump
- > table entry, and is described and depicted on page 61 of Inside
- > Mac II. Second, LoadSeg never returns, because it's intended only
- > as a mechanism for dispatching to routines in unloaded segments;
- > this will cause this loop to never get to its second iteration.
- > Third, due to these limitations, there isn't any prototype for
- > LoadSeg; as far as I know, it can't be called from C or Pascal
- > without writing your own prototype (and then would be very
- > difficult to call correctly).
-
- I really hate to not contradict Mr. Dierks, but he's right. I was tricked
- into thinking that LoadSeg could be called by the THINK Reference. Although
- it the reference does say "LoadSeg is called indirectly...", it didn't jump
- out and say that one CAN'T call it directly. It also gave a high-level
- interface to the call. If I'd given the answer 2 seconds of thought before
- sending it, I'd've realized that you couldn't call LoadSeg.
-
- Well, I guess I'm in good company for being wrong today. Lawrence just
- caught Jon in a boo-boo, too.
-
- Calling a dummy function in each segment would be a way to go, but that's
- not fun. How about using a function loosely based on MacApp's
- PreLoadSegment function? First get the address of _LoadSeg with
- GetTrapAddress. Then call the following function instead of LoadSeg, like I
- showed above.
-
-
- EXPORT PROCEDURE RETURNABLELOADSEG(theSegNum:W)
-
- BEGIN Save=D0-D2/A0-A2
- IMPORT LOADSEGADDRESS
-
- MOVE LOADSEGADDRESS(A5),A0
-
- Move.W theSegNum(FP),-(SP) ; push the original parameter to loadseg
- PEA ComeBack+6 ; push a return address
- ; loadseg will knock 6 off the return
- address
- Jmp (A0) ; Call the original loadseg
-
- ComeBack
-
- Return ; Return to the real world
- EndP
-
-
- - -----
- Keith Rollin
- Phantom Programmer
- Taligent, Inc.
-
- +++++++++++++++++++++++++++
-
- From: werner@soe.berkeley.edu (John Werner)
- Date: 2 Dec 1992 22:16:00 GMT
- Organization: UC Berkeley School of Education
-
- In article <absurd-011292234220@seuss.apple.com>, Tim Dierks wrote:
- > In article <keith-011292131150@kip-15.taligent.com>, Keith Rollin:
- > > int i;
- > > for (i = 0; i < kNumberOfSegs; ++i)
- > > LoadSeg(i);
- > >
- >
- > I really hate to contradict Mr. Rollin, because there's a certain
- > lurking suspicion that I could be incorrect, but this won't help
- > for 3 reasons: first, LoadSeg is a very special trap
-
- How about something like this:
-
- short num = Count1Resources('CODE');
- for (short i = 1; i <= num; i)) {
- Handle hdl = Get1IndResource('CODE', I);
- HLock(hdl);
- HNoPurge(hdl);
- }
-
- This should get all the segments into memory. It won't change the jump
- table to say that they're already loaded. But LoadSeg will take care of
- that (without moving memory) the first time a function in each segment is
- called, so it shouldn't matter.
-
- [By the way, the article I'm following up to had a bogus distrution "comp".
- I changed it to "world.]
-
- - --
- John Werner werner@soe.berkeley.edu
- UC Berkeley School of Education 510-642-9651
-
- +++++++++++++++++++++++++++
-
- From: bowman@reed.edu (BoBoRamDos)
- Date: 2 Dec 92 23:22:40 GMT
- Organization: Reed College, Portland, OR
-
- So, can you recover if RETURNABLELOADSEG fails? That could be mighty handy,
- a bit easier than maintaining a separate heap for code segs, at least sometimes.
- Especially since SADE has a tendency to get very confused when doing that.
-
- cheers,
- bobo In seeking the unattainable,
- bowman@reed.edu simplicity only gets in the way.
- Ask not what's inside your head but what your head's inside of. - W. Mace
-
- +++++++++++++++++++++++++++
-
- From: keith@taligent.com (Keith Rollin)
- Organization: Taligent
- Date: Thu, 3 Dec 1992 01:23:49 GMT
-
- In article <1992Dec2.232240.3040@reed.edu>, bowman@reed.edu (BoBoRamDos)
- wrote:
- >
- >So, can you recover if RETURNABLELOADSEG fails? That could be mighty handy,
- >a bit easier than maintaining a separate heap for code segs, at least sometimes.
- >Especially since SADE has a tendency to get very confused when doing that.
-
-
- Aw, you would bring that up. One thing that you could do have
- RETURNABLELOADSEG call GetResource for the CODE segment you are interested
- in. If that fails, then RETURNABLELOADSEG returns FALSE. If the CODE
- segment loads, then call LoadSeg and return TRUE. MacApp's version does
- this; I just didn't show it in my posting.
-
- - -----
- Keith Rollin
- Phantom Programmer
- Taligent, Inc.
-
- +++++++++++++++++++++++++++
-
- From: keith@taligent.com (Keith Rollin)
- Organization: Taligent
- Date: Thu, 3 Dec 1992 01:27:20 GMT
-
- In article <werner-021292141545@128.32.157.31>, werner@soe.berkeley.edu
- (John Werner) wrote:
- >
- > How about something like this:
- >
- > short num = Count1Resources('CODE');
- > for (short i = 1; i <= num; i)) {
- > Handle hdl = Get1IndResource('CODE', I);
- > HLock(hdl);
- > HNoPurge(hdl);
- > }
- >
- > This should get all the segments into memory. It won't change the jump
- > table to say that they're already loaded. But LoadSeg will take care of
- > that (without moving memory) the first time a function in each segment is
- > called, so it shouldn't matter.
-
- As Lawrence pointed out, the problem with this is that LoadSeg will *still*
- call GetResource. This would require that the proper resource chain be
- swapped in. However, that's not the case under the circumstances of the
- original poster's question.
-
- By the way, you'd probably want a MoveHHi() in there before the HLock().
- Better yet, use HLockHi(). And if the handle's locked, you don't need the
- call to HNoPurge().
-
- - -----
- Keith Rollin
- Phantom Programmer
- Taligent, Inc.
-
- +++++++++++++++++++++++++++
-
- Organization: Royal Institute of Technology, Stockholm, Sweden
- Date: Thu, 3 Dec 1992 12:24:18 GMT
-
- In <1992Dec2.173250.12571@waikato.ac.nz> ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
-
- >This routine isn't going to help. It's just a way of doing at run time
-
- Well, no. Actually, yes, it will help prevent spinning the disk
- re right about it not changing the jump
- tables. For that you could include a function in each and every
- segment that got called on startup to load the segment.
-
- OR: (Hack warning) You could walk the jump table and patch it up yourself.
- s not too hard actually, as long as you make sure to flush the cache.
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
-
- "From now on I will re-label the EQ on the deck as Fizz and Wobble
- instead of HF and LF."
-
- +++++++++++++++++++++++++++
-
- From: bobert@informix.com (Robert Murphy)
- Date: 3 Dec 92 00:49:33 GMT
- Organization: Informix Software, Inc.
-
- Haavard Nord started this thread by talking about problems he is having in
- an interrupt-time completion routine. It calls code in another code segment
- which may not be loaded, and this seems to cause all kinds of trouble which
- he hoped to avoid by preloading all his code segments. A number of people
- have made suggestions about how to do this and how you shouldn't try to load
- code segments at interrupt time (it does the evil deed of moving memory).
-
- Having just been thrashing with PPC completion routines, I'd make one more
- remark. If you're going to call a routine outside the current code segment
- at interrupt time, *** MAKE SURE YOUR A5 WORLD IS SET UP CORRECTLY *** !!!!!
- Otherwise, you will probably be calling code in some other app, and Gopod
- help you if you try to use access any global or static variables. For more
- info on screwing around with A5 worlds in a completion routine, see IM VI
- p. 28-14, and also Tech Note #256, which has a really great discussion of
- A5 worlds in general and why you would want to worry about them.
-
- Bob Murphy
-
- +++++++++++++++++++++++++++
-
- From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
- Date: 4 Dec 92 11:17:42 +1300
- Organization: University of Waikato, Hamilton, New Zealand
-
- tte) writes:
- > In <1992Dec2.173250.12571@waikato.ac.nz> ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
- >
- >>This routine isn't going to help. It's just a way of doing at run time
- >
- > Well, no. Actually, yes, it will help prevent spinning the disk
- > for PowerBook users...
-
- Something else I thought of: I remember a tech note that appeared when the
- Mac Plus first came out. It described a special "fast load" mode in the
- Resource Manager, whereby (if I recall correctly) if you had a bunch of
- preloadable resources stored contiguously in a resource file, they would be
- read into memory with some minimum number of disk reads when the file was
- opened.
-
- Somehow this information never made it into Inside Mac. Is it still true? If
- so, it's another advantage of specifying the preload bit over Jon's run-time
- solution. :-)
-
- Lawrence D'Oliveiro fone: +64-7-856-2889
- Computer Services Dept fax: +64-7-838-4066
- University of Waikato electric mail: ldo@waikato.ac.nz
- Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00
-
- +++++++++++++++++++++++++++
-
- From: anadig@otago.ac.nz
- Date: 8 Dec 92 08:39:27 GMT
- Organization: University of Otago, Dunedin, New Zealand
-
- In article <1992Dec4.111742.12613@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
-
- > Something else I thought of: I remember a tech note that appeared when the
- > Mac Plus first came out. It described a special "fast load" mode in the
- > Resource Manager, whereby (if I recall correctly) if you had a bunch of
- > preloadable resources stored contiguously in a resource file, they would be
- > read into memory with some minimum number of disk reads when the file was
- > opened.
-
- I think you are thinking of JumpStart: not so much a tech note as a utility. It
- rearranged your resource fork so that things were in the order that they
- loaded, using a log that it acquired with another tool. Cute idea: I remember
- that it had a few dangerous modes in which it would relocate the resource map
- and do a few semi-legal things as well. It certainly sped up application
- startup from floppies.
-
- The simpler thing that you can do yourself - and UpdateMaker actually does it
- :-) - is write out all the preloaded resources first when you are building an
- application. As a result applications updated with UpdateMaker may actually
- start up a little bit quicker than the original...
-
-
- Michael(tm) Hamel
-
- Analog Digital Instruments, Dunedin, New Zealand.
-
- +++++++++++++++++++++++++++
-
- From: milton@ccu.umanitoba.ca (Dave Milton)
- Date: 7 Dec 92 17:59:57 GMT
- Organization: University of Manitoba, Winnipeg, Canada
-
- One way to force loading of all segments is to place a simple routine
- which does nothing into each segment. For argument sake you could call
- this ForceName where the Name is the name of the segment; you could
- also use the segment number. At application startup time you can then
- force all of these segments to load by calling all of those routines.
- For example, if you have one segment called printing, a second called
- search, and a third called connect then you could place into your init
- segment a routine
- void ForceLoadSeg()
- {
- ForcePrinting();
- ForceSearch();
- ForceConnect();
- }
-
- Each code segment would contain a routine that does nothing:
- void ForcePrinting() {} // or ForceSearch or ForceConnect
-
- Doing something like the above will cause all modules to load. Since I
- came in at the middle of this thread I may have missed the purpose of
- loading all the code modules at one time. I do have a misgiving about
- doing this kind of thing: it defeats the entire purpose of having a
- program broken into segments. I am under the impression that having
- seperate code segments will reduce the memory footprint of your program.
- A properly segmented program will use much less memory during normal
- operations than a program that simply loads all its segments when it
- starts up. This technique may be useful for testing whether your program
- works well under low memory conditions but beyond that its value is
- dubious IMHO.
-
- Hope this helps
- - --
- David Milton, University of Manitoba, Winnipeg, Canada. (204)788-6346
- Internet: milton@ccu.UManitoba.CA Bitnet: milton@UOFMCC
-
- +++++++++++++++++++++++++++
-
- From: scott@mcl.ucsb.edu (Scott Bronson)
- Date: 11 Dec 92 02:37:17 GMT
-
- In <BywHzy.4C9@ccu.umanitoba.ca> milton@ccu.umanitoba.ca (Dave Milton) writes:
-
- >One way to force loading of all segments is to place a simple routine
- >o load by calling all of those routines.
- >For example, if you have one segment called printing, a second called
- >search, and a third called connect then you could place into your init
- >segment a routine
- > void ForceLoadSeg()
- > {
- > ForcePrinting();
- > ForceSearch();
- > ForceConnect();
- > }
-
- >Each code segment would contain a routine that does nothing:
- > void ForcePrinting() {} // or ForceSearch or ForceConnect
-
- A tiny little thought...
-
- In the (perhaps paranoid) fear that some smart C compiler would
- label my functions as dead code and strip them and calls to them
- (after all, they are optimizing a needless segment load out, quite
- a good optimization IMHO), I simply split my InitMacintosh routine
- into my segments:
-
- void InitMacintosh()
- {
- InitGraf, InitFonts, InitWindows...
- InitPrinting();
- InitSearch();
- InitConnect();
- }
-
- Told ya it was insignificant; I thought it was cool...
-
- +++++++++++++++++++++++++++
-
- From: thomas@camino.mic.cl (Thomas Fruin)
- Date: 27 Dec 92 00:55:22 GMT
- Organization: El Camino
-
-
- In article <keith-021292172408@kip-15.taligent.com> (comp.sys.mac.programmer),
- keith@taligent.com (Keith Rollin) writes:
-
- >By the way, you'd probably want a MoveHHi() in there before the HLock().
- >Better yet, use HLockHi(). And if the handle's locked, you don't need the
- >call to HNoPurge().
- >
- >-----
- >Keith Rollin
- >Phantom Programmer
- >Taligent, Inc.
-
- Hey, what is HLockHi()? I can guess what it does, but I have never seen it
- documented anywhere. Is it MPW glue or a real trap?
-
- - -- Thomas Fruin
-
- thomas@camino.mic.cl
-
- +++++++++++++++++++++++++++
-
- From: d88-jwa@dront.nada.kth.se (Jon Wtte)
- Date: 27 Dec 92 09:46:37 GMT
- Organization: Royal Institute of Technology, Stockholm, Sweden
-
- In <0105013E.m27dq5@camino.mic.cl> thomas@camino.mic.cl (Thomas Fruin) writes:
-
-
- >Hey, what is HLockHi()? I can guess what it does, but I have never seen it
- >documented anywhere. Is it MPW glue or a real trap?
-
- It's glue taking advantage of the passing conventions for
- handle traps to optimize stack and register usage (i.e.
- don't have to adjust stack or reload registers between
- the traps)
-
- And it's not only in MPW.
-
- Cheers,
-
- / h+
-
- - --
- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
- Engineering: "How will this work?" Science: "Why will this work?" Management:
- "When will this work?" Liberal Arts: "Do you want fries with that?"
- -- Jesse N. Schell
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-